package pl.edu.pw.perg.compinfodb.ui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTree;

import org.jdesktop.swingx.JXTable;
import org.springframework.richclient.application.PageComponentContext;
import org.springframework.richclient.application.support.AbstractView;
import org.springframework.richclient.progress.ProgressMonitor;
import org.springframework.richclient.security.ApplicationSecurityManager;

import pl.edu.pw.perg.compinfodb.command.AddEventCommandExecutor;
import pl.edu.pw.perg.compinfodb.command.AddNewCommandExecutor;
import pl.edu.pw.perg.compinfodb.command.EjectElementCommandExecutor;
import pl.edu.pw.perg.compinfodb.command.IActiveModelListener;
import pl.edu.pw.perg.compinfodb.command.InsertElementCommandExecutor;
import pl.edu.pw.perg.compinfodb.command.ReloadEventsCommandExecutor;
import pl.edu.pw.perg.compinfodb.command.SaveEventsCommandExecutor;
import pl.edu.pw.perg.compinfodb.command.SaveModelCommandExecutor;
import pl.edu.pw.perg.compinfodb.datamodel.ConnectorTableModel;
import pl.edu.pw.perg.compinfodb.datamodel.ElementTableModel;
import pl.edu.pw.perg.compinfodb.datamodel.HistoryTableModel;
import pl.edu.pw.perg.compinfodb.datamodel.LogicalDetailsTableModel;
import pl.edu.pw.perg.compinfodb.datamodel.SearchTableModel;
import pl.edu.pw.perg.compinfodb.datamodel.StructureTreeModel;
import pl.edu.pw.perg.compinfodb.entities.User;
import pl.edu.pw.perg.compinfodb.manager.IConnectorManager;
import pl.edu.pw.perg.compinfodb.manager.IConnectorNameManager;

public class StructureManagerView extends AbstractView {

	private StructureTreeModel structureTreeModel;
	private ElementTableModel equipmentTableModel;
	private HistoryTableModel historyTableModel;
	private CustomRendererTableFactory tableFactory = new CustomRendererTableFactory();
	private ConnectorTableModel inputConnectorTableModel = ConnectorTableModel.INPUT;
	private ConnectorTableModel outputConnectorTableModel = ConnectorTableModel.OUTPUT;
	private SearchTableModel searchTableModel = new SearchTableModel();
	private InsertElementCommandExecutor insertElementCommandExecutor;
	private EjectElementCommandExecutor ejectElementCommandExecutor;
	private IConnectorManager connectorManager;
	private IConnectorNameManager connectorNameManager;
	private ApplicationSecurityManager applicationSecurityManager;
	private boolean canEdit;
	private SaveModelCommandExecutor saveModelCommandExecutor;
	private AddNewCommandExecutor addNewCommandExecutor;
	@Override
	protected JComponent createControl() {

		JPanel view = new JPanel(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.BOTH;
		c.weightx = 0.5;
		c.weighty = 0.5;
		c.gridx = 0;
		c.gridy = 0;
		c.gridheight = 1;
		c.gridwidth = 1;
		
		ProgressMonitor pm = getActiveWindow().getStatusBar().getProgressMonitor();
		inputConnectorTableModel.setConnectorManager(connectorManager);
		outputConnectorTableModel.setConnectorManager(connectorManager);
		inputConnectorTableModel.setConnectorNameManager(connectorNameManager);
		outputConnectorTableModel.setConnectorNameManager(connectorNameManager);
		
		LogicalDetailsTableModel ldtm = new LogicalDetailsTableModel();
		JXTable elementsTable = tableFactory.getElementTable(equipmentTableModel);
		JTable propertiesTable = tableFactory.getTable(ldtm);
		JTable historyTable = tableFactory.getHistoryTable(historyTableModel);
		JTree structureTree = new JTree(structureTreeModel);
		JTable inputConnectionsTable = tableFactory.getTable(inputConnectorTableModel);
		JTable outputConnectionsTable = tableFactory.getTable(outputConnectorTableModel);
		JScrollPane inputConnectionsScrPane = new JScrollPane(inputConnectionsTable);
		JScrollPane outputConnectionsScrPane = new JScrollPane(outputConnectionsTable);
		structureTree.setCellRenderer( new EquipmentTreeCellRenderer(getIconSource()));
		structureTree.setRootVisible(false);
		structureTree.setShowsRootHandles(true);
		structureTreeModel.addSelectionListener(ldtm);
		structureTreeModel.setPm(pm);
		structureTree.addTreeSelectionListener(structureTreeModel);
		structureTreeModel.addSelectionListener(equipmentTableModel);
		equipmentTableModel.addPhysicalElementSelectionListener(historyTableModel);
		structureTreeModel.addSelectionListener(inputConnectorTableModel);
		structureTreeModel.addSelectionListener(outputConnectorTableModel);
		structureTreeModel.addSelectionListener(insertElementCommandExecutor);
		structureTreeModel.addSelectionListener(historyTableModel);
//		structureTreeModel.addSelectionListener(ejectElementCommandExecutor);
		elementsTable.setHighlighters(equipmentTableModel.getHighlighter());
		
		JTable search = new JTable(searchTableModel);
		searchTableModel.addTableModelListener(search);
		equipmentTableModel.addColumnModelListener(searchTableModel);
		equipmentTableModel.addMarkedRowSelectionListener(ejectElementCommandExecutor);
		equipmentTableModel.addNoneRowMarkedListener(insertElementCommandExecutor);
		insertElementCommandExecutor.addRefreshListener(equipmentTableModel);
		ejectElementCommandExecutor.addRefreshListener(equipmentTableModel);		
		searchTableModel.addSearchFilterListener(equipmentTableModel);
		equipmentTableModel.recreateColumnModel();
//		equipmentTableModel.addPhysicalElementSelectionListener(addEventExecutor);
		equipmentTableModel.addActiveModelListener(addNewCommandExecutor);
		equipmentTableModel.addPhysicalElementSelectionListener(ejectElementCommandExecutor);
		equipmentTableModel.addPhysicalElementSelectionListener(insertElementCommandExecutor);
//		historyTableModel.addEventModifiactionListener(saveEventsCommandExecutor);
//		historyTableModel.addEventModifiactionListener(reloadEventsCommandExecutor);
//		search.setColumnModel(elementsTable.getColumnModel());
		JScrollPane treeScrPane = new JScrollPane(structureTree);
		JScrollPane elementsScrPane = new JScrollPane(elementsTable);
		JScrollPane propertiesScrPane = new JScrollPane(propertiesTable);
		JScrollPane historyScrPane = new JScrollPane(historyTable);
		search.setTableHeader(null);
		JSplitPane jsp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, search, elementsScrPane);
		jsp.setEnabled(false);


		JSplitPane verticalLeftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, treeScrPane, propertiesScrPane);
		JSplitPane connectorsSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, inputConnectionsScrPane, outputConnectionsScrPane);
		JSplitPane downRightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, connectorsSplitPane, historyScrPane);
		JSplitPane verticalRightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, jsp, downRightSplitPane);	
		JSplitPane horizontalSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, verticalLeftSplitPane,verticalRightSplitPane);
		
		
		verticalLeftSplitPane.setDividerLocation(450);
		verticalRightSplitPane.setDividerLocation(350);
		horizontalSplitPane.setDividerLocation(250);
		downRightSplitPane.setDividerLocation(200);
		connectorsSplitPane.setDividerLocation(450);
		view.add(horizontalSplitPane, c);
		
		canEdit = applicationSecurityManager.isUserInRole(User.WRITE_ROLE);
		equipmentTableModel.setEditable(canEdit);
		equipmentTableModel.addActiveModelListener(saveModelCommandExecutor);
		equipmentTableModel.addModelModificationListener(saveModelCommandExecutor);
		historyTableModel.addActiveModelListener(saveModelCommandExecutor);
		historyTableModel.addModelModificationListener(saveModelCommandExecutor);
		historyTableModel.addActiveModelListener(addNewCommandExecutor);
		structureTreeModel.addActiveModelListener(addNewCommandExecutor);
		structureTreeModel.addActiveModelListener(saveModelCommandExecutor);
		return view;
	}
	
	@Override
	protected void registerLocalCommandExecutors(PageComponentContext context) {
//		context.register("searchModeCommand", searchModeCommand);
		context.register("addNewCommand", addNewCommandExecutor);
//		context.register("saveEventsCommand", saveEventsCommandExecutor);
//		context.register("reloadEventsCommand", reloadEventsCommandExecutor);
		context.register("insertElementCommand", insertElementCommandExecutor);
		context.register("ejectElementCommand", ejectElementCommandExecutor);	
		context.register("saveModelCommand", saveModelCommandExecutor);	
	}


	public void setEquipmentTableModel(ElementTableModel equipmentTableModel) {
		this.equipmentTableModel = equipmentTableModel;
	}


	public void setStructureTreeModel(StructureTreeModel structureTreeModel) {
		this.structureTreeModel = structureTreeModel;
	}


	public void setHistoryTableModel(HistoryTableModel historyTableModel) {
		this.historyTableModel = historyTableModel;
//		addEventExecutor = new AddEventCommandExecutor(historyTableModel);
//		reloadEventsCommandExecutor = new ReloadEventsCommandExecutor(historyTableModel);
//		saveEventsCommandExecutor = new SaveEventsCommandExecutor(historyTableModel);
	}

	public void setInsertElementCommandExecutor(
			InsertElementCommandExecutor putElementCommandExecutor) {
		this.insertElementCommandExecutor = putElementCommandExecutor;
	}

	public void setEjectElementCommandExecutor(
			EjectElementCommandExecutor ejectElementCommandExecutor) {
		this.ejectElementCommandExecutor = ejectElementCommandExecutor;
	}

	public void setConnectorManager(IConnectorManager connectorManager) {
		this.connectorManager = connectorManager;
	}

	public void setApplicationSecurityManager(
			ApplicationSecurityManager applicationSecurityManager) {
		this.applicationSecurityManager = applicationSecurityManager;
	}

	public void setSaveModelCommandExecutor(
			SaveModelCommandExecutor saveModelCommandExecutor) {
		this.saveModelCommandExecutor = saveModelCommandExecutor;
	}

	public void setAddNewCommandExecutor(AddNewCommandExecutor addNewCommandExecutor) {
		this.addNewCommandExecutor = addNewCommandExecutor;
	}

	public void setConnectorNameManager(IConnectorNameManager connectorNameManager) {
		this.connectorNameManager = connectorNameManager;
	}

}
